perm filename BAIL.DOC[DOC,AIL]8 blob
sn#158787 filedate 1975-05-12 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00012 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002
C00003 00003
C00004 00004 This is a test program, run on TENEX.
C00006 00005
C00013 00006 Leap and records, DEC TOPS-10 system.
C00015 00007
C00017 00008 Go back to the earlier examle
C00019 00009 I. Compile-time action
C00026 00010 II. Run-time action
C00036 00011 III. Resources Used
C00038 00012 IV. Current Status
C00040 ENDMK
C⊗;
BAIL -- A debugger for SAIL
John F. Reiser
Computer Science Department
Stanford University
May 10, 1975
This work was supported in part by a National Science Foundation
graduate fellowship. Computer facilities provided by Stanford
Artificial Intelligence Laboratory and Institute for Mathematical
Studies in the Social Sciences, Stanford.
BAIL
BAIL is a debugging aid for SAIL programs. In may respects
BAIL is like DDT or RAID, except that BAIL is oriented towards SAIL
and knows about SAIL data types, primitive operations, and procedure
implementation. In addition, BAIL can display text from the source
file corresponding to the current location in the program.
The first portion of this manual contains several annotated
examples which illustrate the mechanics of using BAIL, and the
features which are available. Technical details are covered in the
second part of the manual.
This is a test program, run on TENEX.
@TYPE TEST1.SAI
; <REISER>TEST1.SAI;1 SAT 10-MAY-75 2:37PM PAGE 1
BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;
INTEGER I,J,K;
STRING A,B,C;
REAL X,Y,Z;
INTEGER ARRAY FOO[0:15]; STRING ARRAY STRARR[1:5,2:6];
INTEGER ITEMVAR DAY; ITEMVAR QQ;
INTEGER PROCEDURE ADD(INTEGER I,J); BEGIN "ADD"
OUTSTR("
HI. GLAD YOU STOPPED BY."); RETURN(I+J) END "ADD";
RECURSIVE INTEGER PROCEDURE FACT(INTEGER N); BEGIN "FACT"
RETURN(IF N LEQ 1 THEN 1 ELSE N*FACT(N-1)) END "FACT";
SIMPLE PROCEDURE SIMPROC(REFERENCE INTEGER M); BEGIN "SBEG"
ADD(M,M←32) END "SBEG";
FOR I←0 STEP 1 UNTIL 15 DO FOO[I]←I*I;
FOR I←1 STEP 1 UNTIL 5 DO
FOR J←2 STEP 1 UNTIL 6 DO
STRARR[I,J]←64+8*I+J;
I←4; J←6; K←112;
A←"BIG DEAL"; B←"QED"; C←"THE LAST PICASSO";
X←3.14159265; Y←0; Z←23.;
BAIL;
ADD(7,45);
SIMPROC(J);
USERERR(0,1,"THIS IS A TEST");
END "TEST";
↑L
Compile and load with BAIL.
@SAIL.SAV;10
TENEX SAIL 8.1 4-4-75 (? FOR HELP)
*TEST1,←
**/27B
**
TEST1.SAI;1 1
END OF COMPILATION.
LOADING
LOADER 6+9K CORE
EXECUTION
↑C
Save the core image for later use.
@SSAVE (PAGES FROM) 0 (TO) 577 (ON) TEST1 [NEW FILE]
[CONFIRM]
Start the program.
@START
BAIL identifies itself
BAIL VER. 10-MAY-75
and the files involved.
TEST1.SM1;2
TEST1.SAI;1
END OF BAIL INITIALIZATION.
1:45;
The "1:" is BAIL's prompt.
It indicates the level of
recursive invocations of BAIL.
See how constants are entered
and printed. The "45;<cr>"
is typed by the user, and
the next line "45" is BAIL's reply.
45
1:7.089;
7.089000
1:"SOME RANDOM STRING";
"SOME RANDOM STRING"
An octal constant; all printout is decimal.
1:'275;
189
Symbolic constants
1:TRUE;
-1
1:FALSE;
0
1:NULL;
""
Variables
1:I;
4
More than one expression requested
1:J,X;
6 3.141593
Assignment
1:I←46;
46
1:I;
46
Relational operators; remember 0 is FALSE.
1:I<J;
0
1:I GEQ J;
-1
1:98 LAND '17;
2
An undeclared identifier
1:XYZ;
UNKNOWN ID: XYZ
;
Usable as a desk calculator
1:45*(89.4-53.06);
1635.300
1:X+J;
9.141593
Function call
1:ADD(3,4);
HI. GLAD YOU STOPPED BY. 7
Argument list checking
1:ADD(3);
ADD TAKES 2 ARGUMENTS.: ADD(3)
;
Arrays
Array name only gives dimension and
subscript bounds information.
1:FOO;
<ARRAY>[ 0:15]
1:FOO[4];
16
Substring notation has been extended
to cover array elements.
1:FOO[5 FOR 3];
25 36 49
1:STRARR;
<ARRAY>[ 1:5 2:6]
1:STRARR[1 FOR 2, 4 TO 6];
"L" "M" "N" "T" "U" "V"
Array accesses are interpreted
1:FOO[35];
SUBSCRIPTING ERROR. INDEX VALUE MIN MAX
1 35 0 15 : FOO[35]
;
LENGTH, LOCATION, and MEMORY
1:LENGTH(A);
8
1:A;
"BIG DEAL"
1:I;
46
1:LOCATION(I);
718
1:MEMORY[718];
46
1:MEMORY[718]←64;
64
1:I;
64
Substringing
1:A[2 TO INF];
"IG DEAL"
1:B[3 TO 4];
"D"
Type-in must be terminated by a semicolon
1:B
;
"QED"
Tracing of procedure entry and exit
1:TRACE("FACT");
1:FACT(4);
ENTERING FACT 4
ENTERING FACT 3
ENTERING FACT 2
ENTERING FACT 1
EXITING FACT= 1
EXITING FACT= 2
EXITING FACT= 6
EXITING FACT= 24
24
1:UNTRACE("FACT");
1:FACT(5);
120
Breakpointing
1:BREAK("ADD");
1:ADD(3,4);
Now one level deeper in BAIL recusion.
ARGS prints the arguments list.
2:ARGS;
3 4
Parameter names evaluate just like variables.
2:I;
3
2:J;
4
2:K;
112
To exit from one level of BAIL
2:!!GO;
HI. GLAD YOU STOPPED BY. 7
The message is from ADD itself;
the value 7 is from BAIL.
Leave another level of BAIL.
1:!!GO;
And come back again. Where are we?
1:TEXT;
Static block structure
LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST
ADD
Dynamic procedure invocations
The #4 means coordinate number 4.
DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE TEXT
ADD #4 INTEGER PROCEDURE ADD(INTEGER I,J); BEGI
TEST #24 ADD(7,45);
SIMPROC(J);
USERERR(0,1,"
1:ARGS;
7 45
Remove the breakpoint.
1:UNBREAK("ADD");
1:!!GO;
Output from other calls in the program
HI. GLAD YOU STOPPED BY.
HI. GLAD YOU STOPPED BY.
THIS IS A TEST
CALLED FROM 642124 LAST SAIL CALL AT 400303
↑B
Entry to BAIL from the error handler
1:TEXT;
LEXICAL SCOPE, TOP DOWN:
$RUN$
DYNAMIC SCOPE, MOST RECENT FIRST:
ROUTINE TEXT
.SIMPLE. '642124 %%% FILE NOT VIEWABLE
TEST #26 USERERR(0,1,"THIS IS A TEST");
END "T
1:I;
UNKNOWN ID: I
;
The static scope needs to be set
back one on the dynamic chain.
1:SETLEX(1);
LEXICAL SCOPE, TOP DOWN:
$RUN$
TEST
1:I;
64
1:C;
"THE LAST PICASSO"
1:!!GO;
END OF SAIL EXECUTION
Leap and records, DEC TOPS-10 system.
.TYPE TEST2.SAI
BEGIN "TEST"
EXTERNAL PROCEDURE BAIL;
REQUIRE 500 SYSTEM!PDL, 10 PNAMES;
LIST L; SET S,S1,S2,S3,S4,S5;
INTEGER ITEM SUNDAY; ITEM MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,
SATURDAY;
INTEGER ITEMVAR DAY; ITEMVAR QQ;
ITEMVAR ARRAY P[1:10];
RECORD!CLASS CELL (RECORD!POINTER(CELL) CAR,CDR);
RECORD!POINTER(CELL) CX,CY;
CX←NEW!RECORD(CELL);
CY←NEW!RECORD(CELL);
CELL:CAR[CX]←NULL!RECORD; CELL:CDR[CX]←NULL!RECORD;
CELL:CAR[CY]←CX; CELL:CDR[CY]←NULL!RECORD;
P[1]←SUNDAY; P[2]←MONDAY;
L←{{SUNDAY}}; DATUM(SUNDAY)←0; DAY←SUNDAY; QQ←MONDAY; S←{QQ};
S1←{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY};
S2←{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY};
S3←{MONDAY,WEDNESDAY,FRIDAY}; S4←{SATURDAY,SUNDAY};
S5←{SUNDAY,FRIDAY};
FOREACH DAY SUCH THAT DAY IN S1 DO MAKE DAY XOR SUNDAY EQV SATURDAY;
BAIL;
USERERR(0,1,"THIS IS A TEST");
END "TEST";
EXIT
↑C
.EXECUTE TEST2.SAI(27B,)
SAIL: TEST2 1
LOADING
LOADER 15K CORE
25K MAX 153 WORDS FREE
EXECUTION
BAIL VER. 10-MAY-75
TEST2.SM1
TEST2.SAI
END OF BAIL INITIALIZATION.
1:L;
{{SUNDAY}}
1:S1;
{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
1:S2;
{MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}
1:S1 INTER S2;
{MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY}
1:S4;
{SUNDAY, SATURDAY}
1:S5;
{SUNDAY, FRIDAY}
1:S4 UNION S5;
{SUNDAY, FRIDAY, SATURDAY}
1:FRIDAY IN S4;
0
1:FRIDAY IN S5;
-1
1:S2<S1;
-1
1:S2<S2;
0
1:S2 LEQ S2;
-1
1:DAY;
SATURDAY
1:DAY←SUNDAY;
SUNDAY
1:DATUM(DAY);
0
1:CX;
CELL.9231
1:CELL:CAR[CX];
NULL!RECORD
1:CELL:CDR[CX];
NULL!RECORD
1:CELL:CAR[CY];
CELL.9231
1:SUNDAY ASSOC SATURDAY;
{SUNDAY}
1:SUNDAY EQV SATURDAY;
{SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}
1:SUNDAY XOR SATURDAY;
PHI
1:SUNDAY EQV SUNDAY;
PHI
1:↑C
Go back to the earlier examle
@TEST1.SAV;1
Initialization uses file created
last time.
BAIL VER. 10-MAY-75 USING TEST1.BAI
END OF BAIL INITIALIZATION.
Switch /27B at compile-time
makes SAIL predeclared runtime
routines known to BAIL.
1:OPENFILE(NULL,"W");
TODAY.TMP
4
1:OUT(4,"THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL.");
1:CFILE(4);
-1
1:OPENFILE("","RC");
TODAY.TMP [OLD VERSION]
4
1:SINI(4,200,"Z");
"THIS IS A TEMPORARY FILE CREATED WHILE IN BAIL."
1:ODTIM(-1,-1);
"SATURDAY, MAY 10, 1975 17:19:29"
Quickie review of BAIL capabilities
1:?
EXPRESSION;
PROCEDURE!CALL;
TRACE("PROCEDURE");
UNTRACE("PROCEDURE");
BREAK("PROCEDURE, BLOCK, OR LABEL");
UNBREAK("PROCEDURE, BLOCK, OR LABEL");
!!GO;
SETLEX(LEVEL);
TEXT;
ARGS;
HELP;
DDT;
?
1:!!GO;
HI. GLAD YOU STOPPED BY.
HI. GLAD YOU STOPPED BY.
THIS IS A TEST
CALLED FROM 642124 LAST SAIL CALL AT 400303
↑
END OF SAIL EXECUTION
@
End of the examples.
I. Compile-time action
The principal result of activating BAIL at compile-time is
the generation of a file of information about the source program for
use by the run-time interpreter. This file has the same name as the
.REL file produced by the compilation, except that the extension is
.SM1. If requested, BAIL will also generate some additional code for
SIMPLE procedures to make them more palatable to the run-time
interpreter.
The action of BAIL at compile time is governed by the value
of the /B switch passed to the compiler. If the value of this switch
is zero (the default if no value is specified) then BAIL is
completely inactive. Otherwise, the low-order bits determine the
actions which BAIL performs. [The value of the /B switch is
interpreted as octal.]
bit action
1 If this bit is on, then the .SM1 file will contain
the program counter to source/listing text directory.
2 If this bit is on, then the .SM1 file will contain
symbol information for all SAIL symbols encountered
in the source. If this bit is off, then information
is kept only for procedures, parameters, blocks, and
internals; i.e., non- internal local variables are
not recorded.
4 If this bit is on, then SIMPLE procedures will get
procedure descriptors, and one additional instruction
(a JFCL 0, which is the fastest machine no-op
instruction) is inserted at the beginning of SIMPLE
procedures. Except for these two changes, all
properties of SIMPLE procedures remain the same as
before. The procedure descriptor is necessary if the
procedure is to be called interpretively or if the
procedure is to be TRACEd.
'10 If this bit is on, then BAIL will not be
automatically loaded and initialized, although all
other actions requested are performed. This is
primarily intended to make it easier to debug new
versions of BAIL without interfering with
SYS:BAIL.REL. By using this switch the decision to
load BAIL is delayed until load time.
'20 If this bit is on, then a request to load
SYS:BAIPDn.REL is generated. This file contains
procedure descriptors for most of the SAIL
predeclared runtime routines, making it possible to
call them from BAIL. The procedure descriptors and
their symbols occupy about 6K.
The B switch must occur on the binary term, not the listing or source
term. Thus:
.R SAIL or .COM PROG(27B,)
*PROG/27B←PROG
The program counter to source/listing index is kept in terms
of coordinates. The coordinate counter is zeroed at the beginning of
the compilation and is incremented by one for each BEGIN, ELSE, and
semicolon seen by the parser, provided at least one word of code has
been compiled since the previous coordinate was defined. Note that
COMMENTs are seen only by the scanner, not the parser, and that
DEFINEs and many declarations merely define symbols and do not cause
instructions to be generated. For each coordinate the directory
contains the coordinate number, the value of the program counter, and
a file pointer to the appropriate place. The appropriate place is
the source file unless a listing file is being produced and the CREF
switch is off, in which case it is the listing file. [The listing
file produced for CREF is nearly unreadable.] On a non-CREF listing,
the program counter is replaced by the coordinate number if bit 1 of
the /B switch is on.
The symbol table information consists of the block structure
and the name, access information, and type for each symbol.
If a BEGIN-END pair has declarations (i.e., is a true block
and not just a compound statement) but does not have a name, then
BAIL will invent one. The name is of the form Bnnnn where nnnn is
the decimal value of the current coordinate.
II. Run-time action
The BAIL run-time interpreter is itself a SAIL program which
resides on the system disk area. This program is usually loaded
automatically, and does some initialization when entered for the
first time.
The initialization generates a .BAI file of information
collected from the .SM1 files produced by separate compilations (if
any). The .SM1 files correspond to .REL files, and the .BAI file
corresponds to the .DMP or .SAV file. Like RPG or CCL, BAIL will try
to bypass much of the initialization and use an existing .BAI file if
appropriate. During initialization BAIL displays the names of the
.SM1 files it is processing. For each .SM1 file which contains
program counter/text index information, BAIL displays the names of
the text files and determines whether the text files are accessable.
The interpreter is activated by explicit call, previously
inserted breakpoints, or the SAIL error handler. For an explicit
call, say EXTERNAL PROCEDURE BAIL; ... BAIL;. From the error
handler, respond B. Breakpoints will be described later in this
section.
Debugging Requests. When entered, BAIL prints the debugging
recursion level followed by a colon, and awaits a debugging request.
Options which are available are
<expression not involving AND, OR, IF-THEN-ELSE, or CASE>;
<procedure!call>;
TRACE("procedure");
UNTRACE("procedure");
BREAK("procedure, block, or label");
UNBREAK("procedure, block, or label");
!!GO;
SETLEX(level);
TEXT;
ARGS;
HELP;
DDT;
?
Expressions and procedure calls are evaluated as if they had
appeared in the source file at the point of the break. TRACE,
UNTRACE, BREAK, and UNBREAK handle breakpoint insertion and deletion.
!!GO resumes execution of the program. SETLEX allows access to the
static environment of dynamic ancestors. TEXT displays the current
static and dynamic scopes, with text from the original source file.
ARGS prints the arguments to the most recently called procedure. DDT
transfers control to an assembly language debugging program (if one
was loaded). HELP and "?" both print the above list.
Breakpoints. Breakpoints are handled by evaluating a call to
one of four procedures defined inside BAIL.
procedure description
TRACE("proc name") Prints the procedure name at each
entry and exit, the parameters at
entry, and the value RETURNed (if
any) at exit.
UNTRACE("proc name") Discontinues tracing of the procedure.
BREAK("location") Plants a breakpoint (a call to BAIL)
at location, which may be a procedure,
label, or block name.
UNBREAK("location") Remove a breakpoint.
Naming conventions: Names defined within the current lexical
(static) scope are always recognized. After that, objects with names
that are globally unique and have a fixed memory location (everything
except parameters and recursive locals) are recognized. After that,
BAIL gives up.
Extended specification of location names:
In case the desired location is not unique, the following extended
syntax may be used.
location := label | procedure | blockname delim location
where delim is any non-identifier character (e.g., altmode, period,
,virgule,space,...). The last blockname should be the block in which
the label or procedure is delared. The complete search algorithm is:
Search the blocks in memory-location order of BEGINs until a block is
found which has the first blockname as its name. If there is a
second blockname, continue the search of the blocks in
memory-location order, beginning with the block which immediately
follows the block which matched the first blockname. Continue until
all blocknames have been matched. This yields some block in the
program. Construct the block structure ancestry of that block. The
label or procedure must then be declared within the scope of one of
the blocks of that ancestry.
Examining variables not in the current lexical scope: The
procedure SETLEX(n) changes the lexical scope to the scope of the
n-th entry in the dynamic scope list. SETLEX(0) is the scope of the
breakpoint; SETLEX(1) is the scope of the most recent procedure call
in the dynamic scope; etc.
BAIL and DDT: If BAIL is initialized in a core image which
does not have DDT or RAID, then things will be set up so that the
monitor command DDT gets you into BAIL in the right way. That is,
BAIL will be your DDT. To enter BAIL from DDT, use
pushi P,<address which BAIL should take as the program counter>$X
JRST BAIL$X
For example, if .JBOPC contains the program counter,
PUSH P,.JBOPC$X
JRST BAIL$X
To enter DDT from BAIL, simply say DDT;.
Syntax extension: The TO and FOR substring and sublist
operators have been extended to operate as array subscript ranges,
FOR PRINT-OUT ONLY. Thus if FOO is an array, then FOO[3 TO 7]; will
act like FOO[3], FOO[4], FOO[5], FOO[6], FOO[7]; but is easier to
type. This extension is for print-out only; no general APL syntax or
semantics are provided.
WARNING: Since BAIL is itself a SAIL procedure, entering BAIL from
the error handler or DDT after a push-down overflow or a string
garbage collection error will get you into trouble.
BAIL and SIMPLE procedures: SIMPLE procedures cause headaches
for BAIL because they do not keep a display pointer. [Indeed, the
compiler gets lost in the following example, and does not complain:
BEGIN "LOST"
PROCEDURE A(INTEGER I); BEGIN "A"
SIMPLE PROCEDURE B; OUTSTR("THE VALUE OF I IS " & CVS(I));
PROCEDURE C(INTEGER J); B;
C(2);
END "A";
A(1);
END "LOST"; ]
BAIL tries valiantly to do the right thing, but occasionally it also
gets lost. BAIL will try to warn you if it can. In general, looking
at value string parameters of SIMPLE procedures does not work.
III. Resources Used
A. Compile-time
1. One channel. This means that REQUIREd source files may only be
nested to a depth of about 9.
2. Memory. Upto 11*(maximum lexical nesting depth) more words of
memory may be required compared with previous compilations.
3. CPU time. Approximately 0.3 seconds per page of dense text.
B. Run-time
1. Channels. Three during initialization, two thereafter. Channels
are obtained via GETCHAN.
2. BAIL uses 7 of the privile7ged breaktables, obtaining them by GETBREAK.
3. REQUIRE 64 STRING!PDL. Necessary if the debugging recursion
level will exceed 3 or 4.
4. Memory. (9.5K +((# of coordinates+127) DIV 128) + (2* # of blocks) +
(5* # of symbols)) words.
5. CPU time.
a. Initialization. Typically 4 seconds for a 30 page program.
b. Debugging requests. 0.07 seconds per simple request.
DDT response time.
C. Disk space
1. The .SM1 file for a /7B compilation is typically one-fourth the
size of the corresponding .REL file.
2. The .BAI file for a group of /7B compilations is typically
one-third the total size of the corresponding .REL files.
IV. Current Status
The state of the world is determined by the values of the accumulators
and the value of the SAIL varaible !SKIP!.
The run-time interpreter recognizes only the first 15 characters of
identifier names; the rest are discarded without comment. The
characters which are legal in identifiers are
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789!_αβπλ⊂⊃∀∃→~#$\|
Notable for its absence: period.
LOCATION of a procedure does not work.
PROPS is read-only.
Bracketed triple items are not allowed.
Functional arguments are not handled correctly.
Contexts are not recognized.
The run-time interpreter will not recognize macros.